

/**
 * load SceneConfiguration and SceneField through .JSON
 *
 */

#ifndef SOLARENERGY_CHIER_SCENELOADER_H
#define SOLARENERGY_CHIER_SCENELOADER_H

#include <boost/json.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>

namespace pt = boost::property_tree;

namespace solar
{
    class SceneConfiguration;
    class SceneField;
    class SceneLoader
    {
        public:
            SceneLoader() = default;

            void setFile(std::string json_file_path);
            void readFile(std::shared_ptr<SceneConfiguration>& config,
                          std::shared_ptr<SceneField>& field);

            auto loadField(std::shared_ptr<SceneField>& field) -> bool;
            auto loadConfig(std::shared_ptr<SceneConfiguration>& config) -> bool;
            // void generateTestFieldConfig();

            // void readFileNoTemplate(std::shared_ptr<SceneConfiguration> &config,
            // std::shared_ptr<SceneField> &field); bool loadFieldNoTemplate(
            // std::shared_ptr<SceneField> &field, std::string file_path); bool
            // loadConfigNoTemplate(std::shared_ptr<SceneConfiguration> &config, std::string
            // file_path);

            // bool read_jsonNoTemplate(std::shared_ptr<SceneConfiguration> &config,
            // std::shared_ptr<SceneField> &field, std::string file_path); void
            // setConfigFromJSONNoTemplate(std::shared_ptr<SceneConfiguration> &config, pt::ptree
            // tree); void setFieldFromJSONNoTemplate(std::shared_ptr<SceneField> &field, pt::ptree
            // tree); void setReceiverFromJSONNoTemplate(std::shared_ptr<SceneField> &field,
            // pt::ptree tree); void setHeliostatFromJSONNoTemplate(std::shared_ptr<SceneField>
            // &field, pt::ptree tree); void setGridWithNumber(std::shared_ptr<SceneField>& field);

        private:
            //         void setConfigFromJSON(std::shared_ptr<SceneConfiguration> &config, pt::ptree
            //         tree);
            void setFieldFromJSON(std::shared_ptr<SceneField>& field, pt::ptree tree);
            void setReceiverFromJSON(std::shared_ptr<SceneField>& field, pt::ptree tree);
            void setHeliostatFromJSON(std::shared_ptr<SceneField>& field, pt::ptree tree);
            //         void setSunRay(std::shared_ptr<SceneConfiguration>
            //         &config,std::shared_ptr<SceneField> &field); void
            //         setGrid(std::shared_ptr<SceneField>& field, pt::ptree tree);

            template <typename T>
            void setHelioOrReceiverProperty(std::shared_ptr<T>& helio_or_rev, std::string property,
                                            pt::ptree tree);
            template <typename T>
            void setGeometryProperty(std::shared_ptr<T>& helio_or_rev, pt::ptree tree);
            template <typename T>
            void setMaterialProperty(std::shared_ptr<T>& helio_or_rev, pt::ptree tree);

        public:
            void readFile_Concise(std::shared_ptr<SceneConfiguration>& config,
                                  std::shared_ptr<SceneField>& field);

            auto read_json(std::shared_ptr<SceneConfiguration>& config,
                           std::shared_ptr<SceneField>& field, std::string file_path) -> bool;
            void setConfigFromJSON(std::shared_ptr<SceneConfiguration>& config, pt::ptree tree);
            void setFieldFromJSON_Concise(std::shared_ptr<SceneField>& field, pt::ptree tree);
            void setReceiverFromJSON_Concise(std::shared_ptr<SceneField>& field, pt::ptree tree);
            void setHeliostatFromJSON_Concise(std::shared_ptr<SceneField>& field, pt::ptree tree);
            void setGridFromJSON(std::shared_ptr<SceneField>& field, pt::ptree tree);
            void setSunray(std::shared_ptr<SceneField>& field,
                           std::shared_ptr<SceneConfiguration> configu);

            std::string json_file_path_; // json文件路径
            // 这里存一下是因为config中需要设置一些material的属性
            std::shared_ptr<SceneConfiguration> config_;

            // 用于测试
            std::shared_ptr<SceneField> field_1, field_2;
            std::shared_ptr<SceneConfiguration> config_1, config_2;
    };
} // namespace solar

#endif // SOLARENERGY_CHIER_SCENELOADER_H
